/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package jxta;

import atributos.ManagerAtributos;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.jxta.peergroup.PeerGroup;
import net.jxta.protocol.PipeAdvertisement;
import net.jxta.socket.JxtaServerSocket;
import utilidades.Manejador;
import utilidades.ManejadorConexion;

/**
 *
 * @author Eduardo
 */
public class ServerSocket implements Runnable {

    private final int BACKLOG = 50;
    private final int TIMEOUT = 0;
    private final long ESPERA_CONEX = Integer.MAX_VALUE;
    private final String MANEJADOR_STRING;
    private final int COMPORTAMIENTO;
    private String idArchivo;
    private String PATH;

    private final PeerGroup netPeerGroup;
    private final PipeAdvertisement pipe;
    private JxtaServerSocket serverSocket;
    private boolean seguir;

    /**
     * El comportamiento por defecto se asigna a ENVIAR.
     * @param peerGroup
     * @param pipe
     */
    public ServerSocket(PeerGroup peerGroup, PipeAdvertisement pipe) {
        this.netPeerGroup = peerGroup;
        this.pipe = pipe;
        this.COMPORTAMIENTO = Manejador.ENVIAR;
        this.MANEJADOR_STRING = ManejadorConexion.class.getName();
        this.PATH = ManagerAtributos.PATH;
    }

    /**
     * Permite seleccionar el comportamiento.
     *
     * @param peerGroup
     * @param pipe
     * @param comportamiento
     */
    public ServerSocket(PeerGroup peerGroup,
            PipeAdvertisement pipe,
            int comportamiento,
            String manejadorClass,
            String path) {
        this.netPeerGroup = peerGroup;
        this.pipe = pipe;
        this.COMPORTAMIENTO = comportamiento;
        this.MANEJADOR_STRING = manejadorClass;
        this.PATH = path;
    }

    /**
     * Asigna el id del archivo que se debe descargar. Es obligatorio en caso de
     * que el comportamiento sea RECIBIR.
     *
     * @param idArchivo El archivo a descargar.
     */
    public void setIdArchivo(String idArchivo) {
        this.idArchivo = idArchivo;
    }

    public void empezar() {
        System.out.println("=========================================================");
        System.out.println("================Starting ServerSocket====================");
        System.out.println("=========================================================");
        serverSocket = null;
        try {
            serverSocket = new JxtaServerSocket(netPeerGroup, pipe, BACKLOG);
            serverSocket.setSoTimeout(TIMEOUT);
        } catch (IOException e) {
            System.out.println("failed to create a server socket");
            e.printStackTrace();
            System.exit(-1);
        }
        long tiempoTermino = System.currentTimeMillis() + ESPERA_CONEX;
        seguir = true;
        while (seguir) {
            //System.out.println("Sigiendo... valor de seguir: " + seguir);
            try {
                System.out.println("Waiting for connections");
                Socket socket = serverSocket.accept();
                if (socket != null) {
                    System.out.println("New socket connection accepted");
                    Manejador manejador = (Manejador) Class.forName(MANEJADOR_STRING).newInstance();
                    //1. Asignar el token
                    manejador.setSocket(socket);
                    //2. Asignar comportamiento. Por defecto el comportamiento es enviar.
                    manejador.setComportamiento(COMPORTAMIENTO);
                    if (COMPORTAMIENTO == Manejador.RECIBIR) {
                        //2.1 Asignar el archivo a descargar. Si aplica.
                        manejador.setIdArchivo(idArchivo);
                    }
                    //3. Asignar la ruta.
                    manejador.setPathname(PATH);
                    Thread thread = new Thread(manejador, "Connection Handler Thread");
                    thread.start();
                }
                long tiempoActual = System.currentTimeMillis();
                if (tiempoActual > tiempoTermino) {
                    seguir = false;
                }
            } catch (SocketException ex) {
                System.out.println("Servicio de servir archivos terminado");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void run() {
        empezar();
    }

    public void pararServicio() {
        try {
            seguir = false;
            serverSocket.close();
            System.out.println("Solicitud de parar servir archivos.");
        } catch (IOException ex) {
            System.err.println("Error intentado cerrar el socket.");
            Logger.getLogger(ServerSocket.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
